import {onMounted, onUnmounted, ref} from 'vue'

// 动画类型定义
export type AnimationType =
  | 'fadeIn' | 'fadeInUp' | 'fadeInDown' | 'fadeInLeft' | 'fadeInRight'
  | 'scaleIn' | 'slideInUp' | 'slideInDown' | 'bounceIn' | 'rotateIn'
  | 'photoReveal' | 'slideUpReveal' | 'glowPulse'

export type AnimationDuration = 'fast' | 'normal' | 'slow' | 'slower'
export type AnimationDelay = 0 | 75 | 100 | 150 | 200 | 300 | 500 | 700 | 1000

// 动画配置接口
export interface AnimationConfig {
  type: AnimationType
  duration?: AnimationDuration
  delay?: AnimationDelay
  once?: boolean
  threshold?: number
}

// 交叉观察器动画
export function useScrollAnimation(config: AnimationConfig) {
  const elementRef = ref<HTMLElement>()
  const isVisible = ref(false)
  const hasAnimated = ref(false)

  let observer: IntersectionObserver | null = null

  const startAnimation = () => {
    if (!elementRef.value) return

    if (config.once && hasAnimated.value) return

    const el = elementRef.value

    // 添加动画类
    el.classList.add(`animate-${config.type}`)

    if (config.duration) {
      el.classList.add(`duration-${getDurationValue(config.duration)}`)
    }

    if (config.delay) {
      el.classList.add(`delay-${config.delay}`)
    }

    hasAnimated.value = true
    isVisible.value = true
  }

  const resetAnimation = () => {
    if (!elementRef.value) return

    const el = elementRef.value
    el.classList.remove(`animate-${config.type}`)

    if (config.duration) {
      el.classList.remove(`duration-${getDurationValue(config.duration)}`)
    }

    if (config.delay) {
      el.classList.remove(`delay-${config.delay}`)
    }

    isVisible.value = false
  }

  const getDurationValue = (duration: AnimationDuration): number => {
    const durationMap = {
      fast: 200,
      normal: 300,
      slow: 500,
      slower: 700
    }
    return durationMap[duration]
  }

  onMounted(() => {
    if (!elementRef.value) return

    observer = new IntersectionObserver(
      (entries) => {
        entries.forEach((entry) => {
          if (entry.isIntersecting) {
            startAnimation()
          } else if (!config.once) {
            resetAnimation()
          }
        })
      },
      {
        threshold: config.threshold || 0.1,
        rootMargin: '50px'
      }
    )

    observer.observe(elementRef.value)
  })

  onUnmounted(() => {
    if (observer && elementRef.value) {
      observer.unobserve(elementRef.value)
      observer.disconnect()
    }
  })

  return {
    elementRef,
    isVisible: readonly(isVisible),
    hasAnimated: readonly(hasAnimated),
    startAnimation,
    resetAnimation
  }
}

// 点击涟漪效果
export function useRippleEffect() {
  const createRipple = (event: MouseEvent, element: HTMLElement) => {
    const rect = element.getBoundingClientRect()
    const size = Math.max(rect.width, rect.height)
    const x = event.clientX - rect.left - size / 2
    const y = event.clientY - rect.top - size / 2

    const ripple = document.createElement('span')
    ripple.style.cssText = `
      position: absolute;
      border-radius: 50%;
      background: rgba(255, 255, 255, 0.6);
      transform: scale(0);
      animation: ripple 0.6s linear;
      left: ${x}px;
      top: ${y}px;
      width: ${size}px;
      height: ${size}px;
    `

    element.appendChild(ripple)

    setTimeout(() => {
      ripple.remove()
    }, 600)
  }

  const addRipple = (element: HTMLElement) => {
    element.style.position = 'relative'
    element.style.overflow = 'hidden'

    const handleClick = (event: MouseEvent) => {
      createRipple(event, element)
    }

    element.addEventListener('click', handleClick)

    return () => {
      element.removeEventListener('click', handleClick)
    }
  }

  return {
    addRipple
  }
}

// 悬停动效管理器
export function useHoverAnimation() {
  const elements = ref<Map<HTMLElement, string>>(new Map())

  const addHoverAnimation = (
    element: HTMLElement,
    animationType: 'lift' | 'scale' | 'rotate' | 'glow' | 'float'
  ) => {
    element.classList.add(`hover-${animationType}`)
    elements.value.set(element, animationType)

    return () => {
      element.classList.remove(`hover-${animationType}`)
      elements.value.delete(element)
    }
  }

  const removeHoverAnimation = (element: HTMLElement) => {
    const animationType = elements.value.get(element)
    if (animationType) {
      element.classList.remove(`hover-${animationType}`)
      elements.value.delete(element)
    }
  }

  onUnmounted(() => {
    elements.value.forEach((animationType, element) => {
      element.classList.remove(`hover-${animationType}`)
    })
    elements.value.clear()
  })

  return {
    addHoverAnimation,
    removeHoverAnimation
  }
}

// 序列动画控制器
export function useSequenceAnimation() {
  const animateSequence = async (
    elements: HTMLElement[],
    animationType: AnimationType,
    staggerDelay = 100
  ) => {
    const promises = elements.map((element, index) => {
      return new Promise<void>((resolve) => {
        setTimeout(() => {
          element.classList.add(`animate-${animationType}`)

          // 监听动画结束
          const handleAnimationEnd = () => {
            element.removeEventListener('animationend', handleAnimationEnd)
            resolve()
          }

          element.addEventListener('animationend', handleAnimationEnd)
        }, index * staggerDelay)
      })
    })

    await Promise.all(promises)
  }

  const resetSequence = (elements: HTMLElement[], animationType: AnimationType) => {
    elements.forEach((element) => {
      element.classList.remove(`animate-${animationType}`)
    })
  }

  return {
    animateSequence,
    resetSequence
  }
}

// 路由转场动画
export function useRouteTransition() {
  const isTransitioning = ref(false)
  const transitionType = ref<'fade' | 'slide' | 'scale'>('fade')

  const beforeEnter = () => {
    isTransitioning.value = true
  }

  const afterEnter = () => {
    isTransitioning.value = false
  }

  const setTransitionType = (type: 'fade' | 'slide' | 'scale') => {
    transitionType.value = type
  }

  return {
    isTransitioning: readonly(isTransitioning),
    transitionType: readonly(transitionType),
    beforeEnter,
    afterEnter,
    setTransitionType
  }
}

// 媒体卡片专用动画
export function useMediaCardAnimation() {
  const animateCardEnter = (element: HTMLElement, index = 0) => {
    element.style.animationDelay = `${index * 0.1}s`
    element.classList.add('animate-slideUpReveal')
  }

  const animatePhotoReveal = (element: HTMLElement) => {
    element.classList.add('animate-photoReveal')
  }

  const animateCardHover = (element: HTMLElement) => {
    element.classList.add('hover-lift')
  }

  const removeCardHover = (element: HTMLElement) => {
    element.classList.remove('hover-lift')
  }

  return {
    animateCardEnter,
    animatePhotoReveal,
    animateCardHover,
    removeCardHover
  }
}

// 状态反馈动画
export function useStatusAnimation() {
  const showSuccess = (element: HTMLElement, message?: string) => {
    element.classList.add('animate-bounceIn')

    if (message) {
      const toast = createToast(message, 'success')
      document.body.appendChild(toast)

      setTimeout(() => {
        toast.remove()
      }, 3000)
    }

    setTimeout(() => {
      element.classList.remove('animate-bounceIn')
    }, 500)
  }

  const showError = (element: HTMLElement, message?: string) => {
    element.classList.add('animate-shake')

    if (message) {
      const toast = createToast(message, 'error')
      document.body.appendChild(toast)

      setTimeout(() => {
        toast.remove()
      }, 3000)
    }

    setTimeout(() => {
      element.classList.remove('animate-shake')
    }, 500)
  }

  const showLoading = (element: HTMLElement) => {
    element.classList.add('animate-pulse')
  }

  const hideLoading = (element: HTMLElement) => {
    element.classList.remove('animate-pulse')
  }

  const createToast = (message: string, type: 'success' | 'error') => {
    const toast = document.createElement('div')
    toast.className = `toast toast--${type} animate-slideInDown`
    toast.textContent = message
    toast.style.cssText = `
      position: fixed;
      top: 20px;
      right: 20px;
      padding: 12px 24px;
      border-radius: 8px;
      color: white;
      font-weight: 500;
      z-index: 9999;
      background: ${type === 'success' ? '#10b981' : '#ef4444'};
      box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
    `
    return toast
  }

  return {
    showSuccess,
    showError,
    showLoading,
    hideLoading
  }
}

// 性能优化的动画管理器
export function useAnimationPerformance() {
  const prefersReducedMotion = ref(false)
  const isHighPerformance = ref(true)

  // 检测用户偏好
  onMounted(() => {
    const mediaQuery = window.matchMedia('(prefers-reduced-motion: reduce)')
    prefersReducedMotion.value = mediaQuery.matches

    mediaQuery.addEventListener('change', (e) => {
      prefersReducedMotion.value = e.matches
    })

    // 检测设备性能
    // @ts-ignore
    if (navigator.hardwareConcurrency <= 4) {
      isHighPerformance.value = false
    }
  })

  const shouldAnimate = (animationType: AnimationType): boolean => {
    if (prefersReducedMotion.value) return false

    // 低性能设备减少复杂动画
    if (!isHighPerformance.value &&
        ['photoReveal', 'glowPulse', 'rotateIn'].includes(animationType)) {
      return false
    }

    return true
  }

  const getOptimalDuration = (duration: AnimationDuration): AnimationDuration => {
    if (prefersReducedMotion.value) return 'fast'
    if (!isHighPerformance.value && duration === 'slower') return 'normal'
    return duration
  }

  return {
    prefersReducedMotion: readonly(prefersReducedMotion),
    isHighPerformance: readonly(isHighPerformance),
    shouldAnimate,
    getOptimalDuration
  }
}

// 导出默认配置
export const defaultAnimationConfig: AnimationConfig = {
  type: 'fadeInUp',
  duration: 'normal',
  delay: 0,
  once: true,
  threshold: 0.1
}
